//! Axum 完整服务器示例
//! 展示如何使用 unified_api 框架构建完整的 Axum 应用

#[cfg(feature = "axum")]
mod axum_impl {
    use axum::{
        extract::{Path, State, Query},
        http::{StatusCode, HeaderMap},
        response::Json,
        routing::{get, post, put, delete},
        Router,
        middleware,
    };
    use serde::{Deserialize, Serialize};
    use std::sync::Arc;
    use tower::ServiceBuilder;
    use tower_http::cors::CorsLayer;
    use tokio::sync::RwLock;
    
    use unified_api::{
        uni_api, auth::{JwtAuthPolicy, AuthPolicy, AuthContext, AuthRequest, AuthResult},
        routers::{RouteInfo, RouteBuilder},
        middleware::{AuthMiddleware, MiddlewareChain, LoggingMiddleware, CorsMiddleware},
        swagger::{SwaggerConfig, SwaggerGenerator}
    };

    #[derive(Debug, Serialize, Deserialize, Clone)]
    struct User {
        id: u64,
        name: String,
        email: String,
        created_at: String,
    }

    #[derive(Debug, Serialize, Deserialize)]
    struct CreateUserRequest {
        name: String,
        email: String,
    }

    #[derive(Debug, Serialize, Deserialize)]
    struct UpdateUserRequest {
        name: Option<String>,
        email: Option<String>,
    }

    #[derive(Debug, Serialize)]
    struct ApiResponse<T> {
        success: bool,
        data: Option<T>,
        message: Option<String>,
        error: Option<String>,
    }

    impl<T> ApiResponse<T> {
        fn success(data: T) -> Self {
            Self {
                success: true,
                data: Some(data),
                message: None,
                error: None,
            }
        }

        fn success_with_message(data: T, message: &str) -> Self {
            Self {
                success: true,
                data: Some(data),
                message: Some(message.to_string()),
                error: None,
            }
        }

        fn error(message: &str) -> Self {
            Self {
                success: false,
                data: None,
                message: None,
                error: Some(message.to_string()),
            }
        }
    }

    // 模拟用户数据库
    struct UserDatabase {
        users: Arc<RwLock<Vec<User>>>,
    }

    impl UserDatabase {
        fn new() -> Self {
            let users = vec![
                User {
                    id: 1,
                    name: "Alice Johnson".to_string(),
                    email: "alice@example.com".to_string(),
                    created_at: "2024-01-01T00:00:00Z".to_string(),
                },
                User {
                    id: 2,
                    name: "Bob Smith".to_string(),
                    email: "bob@example.com".to_string(),
                    created_at: "2024-01-02T00:00:00Z".to_string(),
                },
            ];
            
            Self {
                users: Arc::new(RwLock::new(users)),
            }
        }

        async fn get_all(&self) -> Vec<User> {
            self.users.read().await.clone()
        }

        async fn get_by_id(&self, id: u64) -> Option<User> {
            self.users.read().await.iter().find(|u| u.id == id).cloned()
        }

        async fn create(&self, request: CreateUserRequest) -> User {
            let mut users = self.users.write().await;
            let new_id = users.len() as u64 + 1;
            let user = User {
                id: new_id,
                name: request.name,
                email: request.email,
                created_at: chrono::Utc::now().to_rfc3339(),
            };
            users.push(user.clone());
            user
        }

        async fn update(&self, id: u64, request: UpdateUserRequest) -> Option<User> {
            let mut users = self.users.write().await;
            if let Some(user) = users.iter_mut().find(|u| u.id == id) {
                if let Some(name) = request.name {
                    user.name = name;
                }
                if let Some(email) = request.email {
                    user.email = email;
                }
                Some(user.clone())
            } else {
                None
            }
        }

        async fn delete(&self, id: u64) -> bool {
            let mut users = self.users.write().await;
            let initial_len = users.len();
            users.retain(|u| u.id != id);
            users.len() < initial_len
        }
    }

    // API处理器
    #[uni_api(
        route = "/users",
        method = "GET",
        auth_policy = "permission:users.read",
        description = "获取所有用户列表",
        tags = ["users", "admin"]
    )]
    async fn get_users(
        State(db): State<Arc<UserDatabase>>,
    ) -> Json<ApiResponse<Vec<User>>> {
        let users = db.get_all().await;
        Json(ApiResponse::success(users))
    }

    #[uni_api(
        route = "/users/{id}",
        method = "GET",
        auth_policy = "permission:users.read",
        description = "根据ID获取用户信息",
        tags = ["users"]
    )]
    async fn get_user_by_id(
        Path(id): Path<u64>,
        State(db): State<Arc<UserDatabase>>,
    ) -> Result<Json<ApiResponse<User>>, StatusCode> {
        match db.get_by_id(id).await {
            Some(user) => Ok(Json(ApiResponse::success(user))),
            None => Err(StatusCode::NOT_FOUND),
        }
    }

    #[uni_api(
        route = "/users",
        method = "POST",
        auth_policy = "permission:users.create",
        description = "创建新用户",
        tags = ["users", "admin"]
    )]
    async fn create_user(
        State(db): State<Arc<UserDatabase>>,
        Json(user_data): Json<CreateUserRequest>,
    ) -> Json<ApiResponse<User>> {
        let user = db.create(user_data).await;
        Json(ApiResponse::success_with_message(user, "User created successfully"))
    }

    #[uni_api(
        route = "/users/{id}",
        method = "PUT",
        auth_policy = "user:{id}",
        description = "更新用户信息",
        tags = ["users"]
    )]
    async fn update_user(
        Path(id): Path<u64>,
        State(db): State<Arc<UserDatabase>>,
        Json(user_data): Json<UpdateUserRequest>,
    ) -> Result<Json<ApiResponse<User>>, StatusCode> {
        match db.update(id, user_data).await {
            Some(user) => Ok(Json(ApiResponse::success_with_message(user, "User updated successfully"))),
            None => Err(StatusCode::NOT_FOUND),
        }
    }

    #[uni_api(
        route = "/users/{id}",
        method = "DELETE",
        auth_policy = "role:admin",
        description = "删除用户",
        tags = ["users", "admin"]
    )]
    async fn delete_user(
        Path(id): Path<u64>,
        State(db): State<Arc<UserDatabase>>,
    ) -> Result<Json<ApiResponse<()>>, StatusCode> {
        if db.delete(id).await {
            Ok(Json(ApiResponse::success_with_message((), &format!("User {} deleted successfully", id))))
        } else {
            Err(StatusCode::NOT_FOUND)
        }
    }

    #[uni_api(
        route = "/health",
        method = "GET",
        auth_policy = "",
        description = "健康检查接口",
        tags = ["health"]
    )]
    async fn health_check() -> Json<ApiResponse<serde_json::Value>> {
        let health_data = serde_json::json!({
            "status": "healthy",
            "timestamp": chrono::Utc::now().to_rfc3339(),
            "version": "1.0.0"
        });
        Json(ApiResponse::success(health_data))
    }

    // Swagger文档接口
    async fn swagger_docs() -> Json<serde_json::Value> {
        let config = SwaggerConfig::new("User Management API", "1.0.0")
            .with_description("A comprehensive user management API built with unified_api framework")
            .with_host("localhost:8080")
            .with_base_path("/api");

        let routes = vec![
            RouteInfo::new("/users", "GET", "get_users")
                .with_auth_policy("permission:users.read")
                .with_description("获取所有用户列表")
                .with_tags(vec!["users", "admin"]),
            RouteInfo::new("/users/{id}", "GET", "get_user_by_id")
                .with_auth_policy("permission:users.read")
                .with_description("根据ID获取用户信息")
                .with_tags(vec!["users"]),
            RouteInfo::new("/users", "POST", "create_user")
                .with_auth_policy("permission:users.create")
                .with_description("创建新用户")
                .with_tags(vec!["users", "admin"]),
            RouteInfo::new("/users/{id}", "PUT", "update_user")
                .with_auth_policy("user:{id}")
                .with_description("更新用户信息")
                .with_tags(vec!["users"]),
            RouteInfo::new("/users/{id}", "DELETE", "delete_user")
                .with_auth_policy("role:admin")
                .with_description("删除用户")
                .with_tags(vec!["users", "admin"]),
            RouteInfo::new("/health", "GET", "health_check")
                .with_auth_policy("")
                .with_description("健康检查接口")
                .with_tags(vec!["health"]),
        ];

        let generator = SwaggerGenerator::new(config).add_routes(routes);
        
        match generator.generate() {
            Ok(swagger_doc) => Json(swagger_doc),
            Err(_) => Json(serde_json::json!({
                "error": "Failed to generate Swagger docs"
            })),
        }
    }

    // 认证中间件
    async fn auth_middleware(
        headers: HeaderMap,
        request: axum::extract::Request,
        next: axum::middleware::Next,
    ) -> Result<axum::response::Response, StatusCode> {
        // 获取请求路径
        let path = request.uri().path();
        
        // 跳过健康检查和文档接口的认证
        if path == "/api/health" || path == "/api/docs" {
            return Ok(next.run(request).await);
        }

        // 检查 Authorization header
        if let Some(auth_header) = headers.get("authorization") {
            if let Ok(auth_str) = auth_header.to_str() {
                if auth_str.starts_with("Bearer ") {
                    let token = &auth_str[7..];
                    
                    // 简单的token验证
                    if token == "valid-jwt-token" || token == "admin-token" {
                        return Ok(next.run(request).await);
                    }
                }
            }
        }

        // 返回401未授权
        Err(StatusCode::UNAUTHORIZED)
    }

    // 错误处理
    async fn handle_error(err: StatusCode) -> Json<ApiResponse<()>> {
        let message = match err {
            StatusCode::UNAUTHORIZED => "Unauthorized",
            StatusCode::NOT_FOUND => "Resource not found",
            StatusCode::INTERNAL_SERVER_ERROR => "Internal server error",
            _ => "An error occurred",
        };
        
        Json(ApiResponse::error(message))
    }

    #[tokio::main]
    pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
        println!("🚀 Starting Axum server with unified_api framework");
        println!("📚 Swagger docs available at: http://localhost:8080/api/docs");
        println!("🏥 Health check available at: http://localhost:8080/api/health");

        // 初始化用户数据库
        let db = Arc::new(UserDatabase::new());

        // 配置JWT认证策略
        let jwt_secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "your-secret-key".to_string());
        let _auth_policy = Arc::new(JwtAuthPolicy::new(jwt_secret));

        // 配置中间件链
        let _middleware_chain = MiddlewareChain::new()
            .add_middleware(Arc::new(LoggingMiddleware))
            .add_middleware(Arc::new(CorsMiddleware::default()));

        // 构建路由
        let app = Router::new()
            .route("/users", get(get_users).post(create_user))
            .route("/users/:id", get(get_user_by_id).put(update_user).delete(delete_user))
            .route("/health", get(health_check))
            .route("/docs", get(swagger_docs))
            .with_state(db)
            .layer(
                ServiceBuilder::new()
                    .layer(middleware::from_fn(auth_middleware))
                    .layer(CorsLayer::permissive())
                    .layer(middleware::trace::TraceLayer::new_for_http())
            )
            .fallback(handle_error);

        // 启动服务器
        let listener = tokio::net::TcpListener::bind("127.0.0.1:8082").await?;
        println!("Server listening on http://127.0.0.1:8082");
        
        axum::serve(listener, app).await?;
        
        Ok(())
    }
}

#[cfg(not(feature = "axum"))]
fn main() {
    println!("This example requires 'axum' feature to be enabled.");
    println!("Run with: cargo run --example axum_server --features axum,jwt,swagger");
}

#[cfg(feature = "axum")]
fn main() {
    axum_impl::main();
}